package com.itzhouwei.commerce.redis.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @description:
 * 自定义缓存注解
 * 用于在方法执行之前判断缓存是否存在
 * 存在则直接返回
 * 不存在则查询数据 在设置缓存
 * //需要注意使用这个切面 spring启动类上要标注 @EnableAspectJAutoProxy
 * @author：zw，微信公共号：yingshengzw
 * @date: 2021/8/28
 * @Copyright：公众号：搬砖暗夜码农 | 博客：https://itzhouwei.com - 沉淀、学习、分享、成长，让自己和他人都能有所收获！
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@SuppressWarnings("all")

public @interface MyZwCacheable {

    /***
     * <h1>缓存的名称前缀  缓存名称生成规则 ：{cacheName}:{key}</h1>
     */
    String cacheName();

    /***
     * <h1>缓存的key的表达式 可以使用spring EL 表达式 用于匹配参数值</h1>
     */
    String key();

    /***
     * <h1>缓存的过期时间 单位为秒 默认不设置过期时间</h1>
     */
    int  expireInSeconds() default  0;


    /***
     * <h1>限流器获取令牌等待超时时间</h1>
     */
    int waitInSeconds() default 0;

    //TODO 如果需要限流 可以在这里进行扩展 原理思路大致一样
//    ①有一定性能开销，但是影响不大，spring里面大量使用aop，
//    所以性能基本不需要太多担心。大多数时候aop的性能开销甚至都没有你业务逻辑的
//    开销大。关于性能问题也可以自行测试一下，可以写一个接口，
//    一个用切面，一个不用，然后使用jmeter进行压测看看性能表现。
//    spring的aop不完全使用反射，也会结合动态字节码增强技术。
//
//
//
//            ②需要结合具体业务场景分析，一般比较少在切面编写大量业务代码，
//            技术代码会比较常见，像缓存，日志，鉴权等。而对于共性的业务代码，
//            可以使用面向对象的思想对象进行抽象与封装，也比较便于扩展。
}
